package io.scnb.lesson002.demo2;

import org.junit.Test;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.PropertiesBeanDefinitionReader;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.annotation.AnnotatedBeanDefinitionReader;

import java.util.Arrays;

public class Demo2Test {
    /**
     * xml文件方式bean配置信息解析
     */
    @Test
    public void test1() {
        // 定义一个spring容器，默认实现了BeanDefinitionRegistry，所以本身就是一个bean注册器
        DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
        // 定义一个xml的BeanDefinition读取器，需要传递一个BeanDefinitionRegistry（bean注册器）对象
        XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(factory);
        
        // 指定bean xml配置文件的位置
        String location = "classpath:/io/scnb/lesson002/demo2/beans.xml";
        // 通过xmlBeanDefinitionReader加载xml文件，然后将解析得到的BeanDefinition注册到容器中
        int count = xmlBeanDefinitionReader.loadBeanDefinitions(location);
        System.out.println(String.format("共注册了%s个bean", count));
        
        // 打印出注册的bean配置信息
        for (String beanDefinitionName : factory.getBeanDefinitionNames()) {
            // 通过名称从容器中得到对应的BeanDefinition信息
            BeanDefinition beanDefinition = factory.getBeanDefinition(beanDefinitionName);
            // 获取BeanDefinition具体使用的哪个类
            String beanDefinitionClassName = beanDefinition.getClass().getName();
            // 通过名称获取bean对象
            Object bean = factory.getBean(beanDefinitionName);
            // 打印输出
            System.out.println(beanDefinitionName + ":");
            System.out.println("    beanDefinitionClassName:" + beanDefinitionClassName);
            System.out.println("    beanDefinition:" + beanDefinition);
            System.out.println("    bean:" + bean);
        }
    }

    /**
     * properties文件方式bean配置信息解析
     */
    @Test
    public void test2() {
        // 定义一个spring容器，默认实现了BeanDefinitionRegistry，所以本身是一个bean注册器
        DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
        // 定义一个properties文件的读取器，需要传递一个BeanDefinitionRegistry（bean注册器）对象
        PropertiesBeanDefinitionReader propertiesBeanDefinitionReader = new PropertiesBeanDefinitionReader(factory);
        
        // 指定bean properties配置文件的位置
        String location = "classpath:/io/scnb/lesson002/demo2/beans.properties";
        // 通过PropertiesBeanDefinitionReader加载bean properties文件，然后将解析产生的BeanDefinition注册到容器中
        int count = propertiesBeanDefinitionReader.loadBeanDefinitions(location);
        System.out.println(String.format("共加载了%s个bean", count));
        
        // 打印出注册的bean的配置信息
        for (String beanName : factory.getBeanDefinitionNames()) {
            // 通过bean名称从容器中拿出对应的BeanDefinition
            BeanDefinition beanDefinition = factory.getBeanDefinition(beanName);
            // 获取BeanDefinition具体使用的是哪个类
            String beanDefinitionClassName = beanDefinition.getBeanClassName();
            // 通过名称获取bean对象
            Object bean = factory.getBean(beanName);
            //打印输出
            System.out.println(beanName + ":");
            System.out.println("    beanDefinitionClassName：" + beanDefinitionClassName);
            System.out.println("    beanDefinition：" + beanDefinition);
            System.out.println("    bean：" + bean);
        }
    }
    
    @Test
    public void test3() {
        // 定义一个spring容器，默认实现了BeanDefinitionRegistry，所以本身是一个bean注册器
        DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
        // 定义一个properties文件的读取器，需要传递一个BeanDefinitionRegistry（bean注册器）对象
        AnnotatedBeanDefinitionReader annotatedBeanDefinitionReader = new AnnotatedBeanDefinitionReader(factory);

        // 注册组件类，用于后续处理
        annotatedBeanDefinitionReader.register(Service1.class, Service2.class);
                
        factory.getBeansOfType(BeanPostProcessor.class).values().forEach(factory::addBeanPostProcessor);
        // 打印出注册的bean的配置信息
        for (String beanName : Arrays.asList("service1", "service2")) {
            // 通过bean名称从容器中拿出对应的BeanDefinition
            BeanDefinition beanDefinition = factory.getBeanDefinition(beanName);
            // 获取BeanDefinition具体使用的是哪个类
            String beanDefinitionClassName = beanDefinition.getBeanClassName();
            // 通过名称获取bean对象
            Object bean = factory.getBean(beanName);
            //打印输出
            System.out.println(beanName + ":");
            System.out.println("    beanDefinitionClassName：" + beanDefinitionClassName);
            System.out.println("    beanDefinition：" + beanDefinition);
            System.out.println("    bean：" + bean);
        }
    }
}
